/**
 * ExportXlsFileTemplate.java
 * Created at 2016年5月12日
 * Created by Jackie Liu
 * Copyright (C) 2016, All rights reserved.
 */
package com.huabo.excel;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import jxl.Workbook;
import jxl.write.Label;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import jxl.write.WriteException;
import jxl.write.biff.RowsExceededException;

/**
 * <p>ClassName: ExportXlsFileTemplate</p>
 * <p>Description: 导出excel文件</p>
 * <p>Author: Jackie Liu</p>
 * <p>Date: 2016年5月12日</p>
 */
public class ExportXlsFileTemplate<T> implements FileExport<T> {

	private List<T> list;
	private String[] titles;
	
	private WritableWorkbook workBook;
	private WritableSheet sheet;
	private int rowNum = 1;
	private int columnNum = 0;
	private int sheetNum = 0;
	
	/**
	 * <p>Description: 有参构造函数</p>
	 * @param response HttpServletResponse实例
	 * @throws IOException
	 */
	public ExportXlsFileTemplate(HttpServletResponse response) throws IOException {
		workBook = Workbook.createWorkbook(response.getOutputStream());
		sheet = workBook.createSheet("sheet", sheetNum);
	}
	
	/**
	 * <p>Description: 构造对象时注入数据</p>
	 * @param list 导出数据
	 * @throws IOException 
	 */
	public ExportXlsFileTemplate(List<T> list, HttpServletResponse response) throws IOException {
		this.list = list;
		workBook = Workbook.createWorkbook(response.getOutputStream());
		sheet = workBook.createSheet("sheet", sheetNum);
	}
	
	/**
	 * <p>Description: 创建新的sheet</p>
	 * @param sheetName sheet名称
	 */
	public void newSheet(String sheetName) {
		sheetNum ++;
		rowNum = 1;
		columnNum = 0;
		sheet = workBook.createSheet(sheetName, sheetNum);
	}
	
	/* (non-Javadoc)
	 * <p>Title: export</p>
	 * <p>Description: </p>
	 * @param targetPath
	 * @see com.huabo.spsp.export.FileExport#export(java.lang.String)
	 */
	@Override
	public void export(String targetPath) {
		
	}

	/* (non-Javadoc)
	 * <p>Title: setTitle</p>
	 * <p>Description: </p>
	 * @param titles
	 * @see com.huabo.spsp.export.FileExport#setTitle(java.lang.String[])
	 */
	@Override
	public void setTitle(String[] titles) {
		this.titles = titles;
	}

	/* (non-Javadoc)
	 * <p>Title: setList</p>
	 * <p>Description: </p>
	 * @param list
	 * @see com.huabo.spsp.export.FileExport#setList(java.util.List)
	 */
	@Override
	public void setList(List<T> list) {
		this.list = list;
	}

	/* (non-Javadoc)
	 * <p>Title: clear</p>
	 * <p>Description: </p>
	 * @see com.huabo.spsp.export.FileExport#clear()
	 */
	@Override
	public void clear() {
		list = null;
		titles = null;
		
		rowNum = 1;
		columnNum = 0;
	}

	/* (non-Javadoc)
	 * <p>Title: export</p>
	 * <p>Description: </p>
	 * @return
	 * @see com.huabo.spsp.export.FileExport#export()
	 */
	@Override
	public Object export() {
		try {
			if (titles != null && titles.length > 0) {
				for (int i = 0; i < titles.length; i ++) {
					Label label = new Label(i, 0, titles[i]);  
			        sheet.addCell(label);  
		        }
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return workBook;
	}

	/* (non-Javadoc)
	 * <p>Title: buildFile</p>
	 * <p>Description: </p>
	 * @param callBack
	 * @see com.huabo.spsp.export.FileExport#buildFile(com.huabo.spsp.export.BuildFileCallBack)
	 */
	@Override
	public void buildFile(BuildFileCallBack<T> callBack) {
		if (list == null) {
			throw new NullPointerException("数据不存在");
		}
		if (callBack == null) {
			throw new NullPointerException("解析方式回调对象不存在");
		}
		
		for (T t : list) {
			callBack.execute(t);
			this.newLine();
		}
	}

	/* (non-Javadoc)
	 * <p>Title: appendData</p>
	 * <p>Description: </p>
	 * @param data
	 * @see com.huabo.spsp.export.FileExport#appendData(java.lang.String)
	 */
	@Override
	public void appendData(String data) {
        try {
        	if (data != null) {
        		Label label = new Label(columnNum, rowNum, data);  
    			sheet.addCell(label);
        	}
		} catch (RowsExceededException e) {
			e.printStackTrace();
		} catch (WriteException e) {
			e.printStackTrace();
		}
        columnNum ++;
	}

	/* (non-Javadoc)
	 * <p>Title: appendData</p>
	 * <p>Description: </p>
	 * @param data
	 * @see com.huabo.spsp.export.FileExport#appendData(int)
	 */
	@Override
	public void appendData(int data) {
        try {
        	jxl.write.Number number = new jxl.write.Number(columnNum, rowNum, data);  
			sheet.addCell(number);
		} catch (RowsExceededException e) {
			e.printStackTrace();
		} catch (WriteException e) {
			e.printStackTrace();
		}
        columnNum ++;
	}

	/* (non-Javadoc)
	 * <p>Title: appendData</p>
	 * <p>Description: </p>
	 * @param data
	 * @see com.huabo.spsp.export.FileExport#appendData(float)
	 */
	@Override
	public void appendData(float data) {
		try {
        	jxl.write.Number number = new jxl.write.Number(columnNum, rowNum, data);  
			sheet.addCell(number);
		} catch (RowsExceededException e) {
			e.printStackTrace();
		} catch (WriteException e) {
			e.printStackTrace();
		}
		columnNum ++;
	}

	/* (non-Javadoc)
	 * <p>Title: appendData</p>
	 * <p>Description: </p>
	 * @param data
	 * @see com.huabo.spsp.export.FileExport#appendData(double)
	 */
	@Override
	public void appendData(double data) {
		try {
        	jxl.write.Number number = new jxl.write.Number(columnNum, rowNum, data);  
			sheet.addCell(number);
		} catch (RowsExceededException e) {
			e.printStackTrace();
		} catch (WriteException e) {
			e.printStackTrace();
		}
		columnNum ++;
	}

	/* (non-Javadoc)
	 * <p>Title: appendData</p>
	 * <p>Description: </p>
	 * @param data
	 * @see com.huabo.spsp.export.FileExport#appendData(boolean)
	 */
	@Override
	public void appendData(boolean data) {
		try {
    		Label label = new Label(columnNum, rowNum, String.valueOf(data));  
			sheet.addCell(label);
		} catch (RowsExceededException e) {
			e.printStackTrace();
		} catch (WriteException e) {
			e.printStackTrace();
		}
        columnNum ++;
	}

	/* (non-Javadoc)
	 * <p>Title: newLine</p>
	 * <p>Description: </p>
	 * @see com.huabo.spsp.export.FileExport#newLine()
	 */
	@Override
	public void newLine() {
		rowNum ++;
		columnNum = 0;
	}

	/* (non-Javadoc)
	 * <p>Title: write</p>
	 * <p>Description: </p>
	 * @param response
	 * @param name
	 * @see com.huabo.spsp.export.FileExport#write(javax.servlet.http.HttpServletResponse, java.lang.String)
	 */
	@Override
	public void write(HttpServletResponse response, String name) {
	    try {
	    	response.reset();  
		    response.setContentType("application/vnd.ms-excel;charset=UTF-8");  
		    response.setHeader("Content-Disposition", "attachment;filename=" + new String((name + ".xls").getBytes("GBK"), "iso8859-1"));  
		    
		    export();
		    response.getOutputStream().flush();
			workBook.write();  
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (workBook != null) {
					workBook.close();
				}
			} catch (WriteException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			} 
			try {
				response.getOutputStream().close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	
	/**
	 * 
	 * @param list
	 * @param response
	 * @throws IOException
	 */
	public ExportXlsFileTemplate(List<T> list, OutputStream out) throws IOException {
		this.list = list;
		workBook = Workbook.createWorkbook(out);
		sheet = workBook.createSheet("sheet", sheetNum);
	}
	
	public void write(){
		try {
			export();
			workBook.write();
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			try {
				workBook.close();
			} catch (WriteException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		
		
	}
	
	
	public static void main(String[] args) {
		try {
			File file = new File("E://test//temp.xls");
			if(!file.exists()){
				if(!file.getParentFile().exists()){
					file.getParentFile().mkdirs();
				}
				file.createNewFile();
			}
			OutputStream fos = new FileOutputStream(file);
			/*WritableWorkbook wb = Workbook.createWorkbook(fos);
			WritableSheet wbs = wb.createSheet("test", 0);
			wbs.addCell(new Label(1, 1, "t1"));
			wbs.addCell(new Label(2, 1, "t2"));
			wb.write();
			wb.close();*/
			List<Map<String,Object>> errorMessageList = new ArrayList<>();
			errorMessageList.add(new HashMap<String,Object>());
			final FileExport<Map<String, Object>> exp = new ExportXlsFileTemplate<Map<String, Object>>(errorMessageList, fos);
            exp.setTitle(new String[]{"身份证号", "姓名", "人员类别", "简要案情", "申请人", "申请人电话", "被布控人户籍地详址", "现住址","错误原因"});
            exp.buildFile(new BuildFileCallBack<Map<String, Object>>() {
                @Override
                public void execute(Map<String, Object> messageMap) {
                	exp.appendData("1");
                	exp.appendData("1");
                	exp.appendData("1");
                	exp.appendData("1");
                	exp.appendData("1");
                	exp.appendData("1");
                	exp.appendData("1");
                	exp.appendData("1");
                	exp.appendData("1");
                }
            });
            //exp.write(response, errorFileName);
            WritableWorkbook wb = (WritableWorkbook) exp.export();
			wb.write();
			wb.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}

}
